#include <stdio.h>
#include <omp.h>
#define N 1000

// 单精度部分
float sp[N], sv1[N], sv2[N];
void s_init(float* v1, float* v2, int size) {
    int i;
    for (i = 0; i < size; i++) {
        v1[i] = i * 1.0f;
        v2[i] = i * 0.5f;
    }
}
void s_output(float* p, int size) {
    int i;
    for (i = 0; i < 5; i++) {
        printf("sp[%d] = %.2f\n", i, p[i]);
    }
}
#pragma omp declare target
void s_vec_mult_accum() {
    int i;
    #pragma omp target map(to:sv1, sv2) map(from:sp)
    #pragma omp parallel for
    for (i = 0; i < N; i++) {
        sp[i] = sv1[i] * sv2[i];
    }
}
#pragma omp end declare target

// 双精度部分
double dp[N], dv1[N], dv2[N];
void d_init(double* v1, double* v2, int size) {
    int i;
    for (i = 0; i < size; i++) {
        v1[i] = i * 1.0;
        v2[i] = i * 0.5;
    }
}
void d_output(double* p, int size) {
    int i;
    for (i = 0; i < 5; i++) {
        printf("dp[%d] = %.2f\n", i, p[i]);
    }
}
#pragma omp declare target
void d_vec_mult_accum() {
    int i;
    #pragma omp target map(to:dv1, dv2) map(from:dp)
    #pragma omp parallel for
    for (i = 0; i < N; i++) {
        dp[i] = dv1[i] * dv2[i];
    }
}
#pragma omp end declare target

int main() {
    s_init(sv1, sv2, N);
    s_vec_mult_accum();
    s_output(sp, N);
    d_init(dv1, dv2, N);
    d_vec_mult_accum();
    d_output(dp, N);
    return 0;
}